package com.example.gameapplication.view;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.example.gameapplication.R;
import com.example.gameapplication.activity.ControlDialogActivity;
import com.example.gameapplication.activity.MainActivity;
import com.example.gameapplication.bullet.BossSkill;
import com.example.gameapplication.bullet.BulletBuff;
import com.example.gameapplication.bullet.Skill;
import com.example.gameapplication.bullet.WindmillSkill;
import com.example.gameapplication.database.DataUtils;
import com.example.gameapplication.plant.BigPlane;
import com.example.gameapplication.plant.BossPlane;
import com.example.gameapplication.plant.MiddlePlane;
import com.example.gameapplication.plant.SmallPlane;
import com.example.gameapplication.plant.MainPlane;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * 因为刚刚开始做的时候，许多实现方式没考虑，比如计算伤害，可以在DataUtils中写一个静态方法，让一个子线程专门遍历调用计算伤害，毕竟全局所有对象都已在里边了，很容易实现。
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    private SurfaceHolder mHolder;
    private ExecutorService executorService;
    private Canvas mCanvas;
    private Paint paint;
    private MainPlane mainPlane;
    private Bitmap background2;
    private Bitmap background;
    private float scalex;
    private float scaley;
    private float bg_y; // 图片的坐标
    private float bg_y2;
    List<SmallPlane> smallPlanes;
    List<MiddlePlane> middlePlanes;
    List<BossPlane> bossPlanes;
    private ArrayList<BulletBuff> bulletBuffs;
    private Bitmap playButton;
    private int playButtonWidth;
    private int playButtonHeight;
    private MediaPlayer mMediaPlayer;
    private Bitmap lifeIcon;
    private int lifeIconWidth;
    private int lifeIconHeight;
    private Bitmap missile;
    private int missileWidth;
    private int missileHeight;
    private Skill skill;
    private BossSkill bossSkill;
    private boolean startScreen;//后台回来画面是黑色的，需要播放一帧。
    private List<BigPlane> bigPlanes;
    private WindmillSkill windmillSkill;


    public GameView(Context context) {
        super(context);
        init();
    }

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    protected void init() {
        // 背景音乐
        mMediaPlayer = MediaPlayer.create(getContext(), R.raw.game);
        mMediaPlayer.setLooping(true);
        if (!mMediaPlayer.isPlaying()) {
            mMediaPlayer.start();
        }
        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);
        executorService = DataUtils.getExecutorService();//用线程池，不要频繁创建线程，否则app会崩。这里我使用单线程的线程池。
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Resources resources = getResources();
        background = DataUtils.getBackground(resources);
        background2 = DataUtils.getBackground2(resources);
        bg_y = DataUtils.getBg_y();
        bg_y2 = DataUtils.getBg_y2();
        playButton = DataUtils.getPlayButton(resources);
        lifeIcon = DataUtils.getLifeIcon(resources);
        missile = DataUtils.getMissile(resources);
        DataUtils.setGameViewWidth(getMeasuredWidth());
        DataUtils.setGameViewHight(getMeasuredHeight());
        missileWidth = missile.getWidth();
        missileHeight = missile.getHeight();
        lifeIconWidth = lifeIcon.getWidth();
        lifeIconHeight = lifeIcon.getHeight();
        playButtonWidth = playButton.getWidth();
        playButtonHeight = playButton.getHeight() / 2;
        scalex = (float) (1.0 * getMeasuredWidth() / background.getWidth());//图片宽高比例与view的宽高比例
        scaley = (float) (1.0 * getMeasuredHeight() / background.getHeight());
        paint = DataUtils.getPaint();
        mainPlane = DataUtils.getmainPlane(resources);
        smallPlanes = DataUtils.getSmallPlanes();
        middlePlanes = DataUtils.getMiddlePlanes();
        bigPlanes = DataUtils.getBigPlanes();
        bossPlanes = DataUtils.getBossPlanes();
        bulletBuffs = DataUtils.getBulletBuffs();
        skill = DataUtils.getSkill(resources);//第一次创建的时候会初始化
        windmillSkill = DataUtils.getWindmillSkill(resources);
        bossSkill = DataUtils.getBossSkill(resources);//第一次创建的时候会初始化
        if (bulletBuffs.size() == 0) {
            BulletBuff bulletBuff = new BulletBuff(getResources(), paint);
            bulletBuff.setMainPlane(mainPlane);
            bulletBuffs.add(bulletBuff);
        }

        startScreen = true;
        executorService.execute(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        DataUtils.setIsPlaying(false);
        mainPlane.dataDestroyed();
        if (!background.isRecycled()) {
            background.recycle();
        }
        if (!background2.isRecycled()) {
            background2.recycle();
        }
        if (smallPlanes != null) {
            for (SmallPlane smallPlane : smallPlanes) {
                smallPlane.dataDestroyed();
            }
        }
        if (middlePlanes != null) {
            for (MiddlePlane middlePlane : middlePlanes) {
                middlePlane.dataDestroyed();
            }
        }
        if (bigPlanes != null) {
            for (BigPlane bigPlane : bigPlanes) {
                bigPlane.dataDestroyed();
            }
        }
        if (bossPlanes != null) {
            for (BossPlane bossPlane : bossPlanes) {
                bossPlane.dataDestroyed();
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if (event.getPointerCount() == 2) {
            mainPlane.setOnPress(false);
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (x > 10 && x < 10 + playButtonWidth && y > 10 && y < 10 + playButtonHeight) {//按到了暂停继续按钮
                    DataUtils.setIsPlaying(!DataUtils.isIsPlaying());
                    MainActivity.palySound(7,0);
                    if (!DataUtils.isIsPlaying()) {
                        getContext().startActivity(new Intent(getContext(),ControlDialogActivity.class));
                    }
                    startScreen = true;
                    executorService.execute(this);
                } else if (x > 10 && x < 10 + missileWidth && y > getMeasuredHeight() * 9 / 10 - lifeIconHeight - missileHeight && y < getMeasuredHeight() * 9 / 10 - lifeIconHeight) {//点击了技能按钮
                    skill.launchSkill();
                }
                mainPlane.checkOnclick(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                mainPlane.setOnPress(false);
                break;
        }
        mainPlane.setSeat(x, y);
        return true;
    }

    @Override
    public void run() {
        while (DataUtils.isIsPlaying() || startScreen) {
            startScreen = false;//播放完1帧之后改为false
            try {
                if (DataUtils.isInvincible()) {
                    mainPlane.unbeatable++;
                }
                long startTime = System.currentTimeMillis();
                //锁定画布并返回画布对象
                mCanvas = mHolder.lockCanvas();
//                mCanvas = mHolder.lockHardwareCanvas();//硬件加速的画板，但是当cpu高使用率，比如说战机同时出现好几百台，反而会卡，表现不平稳
                //接下去就是在画布上进行一下draw
                mCanvas.drawColor(Color.WHITE);
                mCanvas.save();
                // 计算背景图片与屏幕的比例
                mCanvas.scale(scalex, scaley, 0, 0);//控制第一第二参数使得手机屏幕满屏，其实可以计算的	canvas.scale(scalex, scaley, 0, 0);
                mCanvas.drawBitmap(background, 0, bg_y, paint); // 绘制背景图
                mCanvas.drawBitmap(background2, 0, bg_y2, paint); // 绘制背景图
                mCanvas.restore();
                for (int i = 0; i < smallPlanes.size(); i++) {
                    smallPlanes.get(i).drawSelf(mCanvas);
                }
                for (int i = 0; i < middlePlanes.size(); i++) {
                    middlePlanes.get(i).drawSelf(mCanvas);
                }
                for (int i = 0; i < bigPlanes.size(); i++) {
                    bigPlanes.get(i).drawSelf(mCanvas);
                }
                for (int i = 0; i < bossPlanes.size(); i++) {
                    bossPlanes.get(i).drawSelf(mCanvas);
                }
                bossSkill.drawSelf(mCanvas);
                skill.drawSelf(mCanvas);
                if (mainPlane.getLv()>=DataUtils.getWindMillBulletStartLv())
                    windmillSkill.drawSelf(mCanvas);
                for (BulletBuff bulletBuff: bulletBuffs ) {//add方法里边设置了它的alive，有时间间隔
                    bulletBuff.drawSelf(mCanvas);
                }
                mainPlane.drawSelf(mCanvas);
                mCanvas.save();
                //画暂停按钮
                mCanvas.clipRect(10, 10, 10 + playButtonWidth, 10 + playButtonHeight);
                if (DataUtils.isIsPlaying()) {
                    mCanvas.drawBitmap(playButton, 10, 10, paint);
                } else {
                    mCanvas.drawBitmap(playButton, 10, 10 - playButtonHeight, paint);
                }
                mCanvas.restore();
                // 绘制积分文字
                mCanvas.drawText("积分:" + String.valueOf(DataUtils.getAllScore()), 30 + playButtonWidth, 50, paint);
                mCanvas.drawText("无敌剩余：" + mainPlane.unbeatable, 10, 40 + playButtonHeight, paint);
                mCanvas.save();//生命图片
                mCanvas.clipRect(10, getMeasuredHeight() * 9 / 10 - lifeIconHeight, 10 + lifeIconWidth, getMeasuredHeight() * 9 / 10);
                mCanvas.drawBitmap(lifeIcon, 10, getMeasuredHeight() * 9 / 10 - lifeIconHeight, paint);
                mCanvas.restore();
                mCanvas.drawText(String.valueOf(DataUtils.getMylife()), 10 + lifeIconWidth * 10 / 9, getMeasuredHeight() * 9 / 10 - lifeIconHeight / 2, paint);
                mCanvas.save();
                mCanvas.clipRect(10, getMeasuredHeight() * 9 / 10 - lifeIconHeight - missileHeight, 10 + missileWidth, getMeasuredHeight() * 9 / 10 - lifeIconHeight);
                mCanvas.drawBitmap(missile, 10, getMeasuredHeight() * 9 / 10 - lifeIconHeight - missileHeight, paint);
                mCanvas.restore();
                mCanvas.drawText(String.valueOf(DataUtils.getSkillSum()), 10 + missileWidth, getMeasuredHeight() * 9 / 10 - lifeIconHeight - missileHeight / 2, paint);
                DataUtils.runEnemyBulletAttack();//敌方子弹攻击
                DataUtils.runAttack();//我方子弹与敌方战机相遇，和我方战机与地方战机碰撞
                DataUtils.runGetBuff();//检查是否获取升级物品
                addSmallPlane();
                addmiddleplane();
                addbigplane();
                addbossplane();
                addBuff();

                viewLogic(); // 背景移动的逻辑
                long endTime = System.currentTimeMillis();
                if (startTime - endTime < 80) {

                    Thread.sleep(60);
                }
            } catch (Exception e) {
                Log.e("AACC", "Exception:GameView: " + e.toString());
                e.printStackTrace();
            } finally {
                //当画布内容不为空时，才post，避免出现黑屏的情况。
                if (mCanvas != null)
                    mHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }

    private void addbossplane() {
        if (bossPlanes.size() == DataUtils.getBossMaxSum()) return;//大部分情况下我们不会改变max，所以加这个判断可微微提高性能
        while (bossPlanes.size() > DataUtils.getBossMaxSum()) {
            bossPlanes.get(0).dataDestroyed();
            bossPlanes.remove(0);
        }
        if (bossPlanes.size() == DataUtils.getBossMaxSum()) return;
        BossPlane bossPlane = new BossPlane(getResources(), paint);
        bossPlane.setMainPlane(mainPlane);
        bossPlanes.add(bossPlane);
    }

    private void addbigplane() {
        if (bigPlanes.size() == DataUtils.getBigMaxSum()) return;
        while (bigPlanes.size() > DataUtils.getBigMaxSum()) {
            bigPlanes.get(0).dataDestroyed();
            bigPlanes.remove(0);
        }
        if (bigPlanes.size() == DataUtils.getBigMaxSum()) return;
        BigPlane smallPlane = new BigPlane(getResources(), paint);
        smallPlane.setMainPlane(mainPlane);
        bigPlanes.add(smallPlane);
    }

    private void addmiddleplane() {
        if (middlePlanes.size() == DataUtils.getMiddleMaxSum()) return;
        while (middlePlanes.size() > DataUtils.getMiddleMaxSum()) {
            middlePlanes.get(0).dataDestroyed();
            middlePlanes.remove(0);
        }
        if (middlePlanes.size() == DataUtils.getMiddleMaxSum()) return;
        MiddlePlane smallPlane = new MiddlePlane(getResources(), paint);
        smallPlane.setMainPlane(mainPlane);
        middlePlanes.add(smallPlane);
    }

    public void addSmallPlane() {
        if (smallPlanes.size() == DataUtils.getSmallMaxSum()) return;
        while (smallPlanes.size() > DataUtils.getSmallMaxSum()) {
            smallPlanes.get(0).dataDestroyed();
                    smallPlanes.remove(0);
        }
        if (smallPlanes.size() == DataUtils.getSmallMaxSum()) return;
        SmallPlane smallPlane = new SmallPlane(getResources(), paint);
        smallPlane.setMainPlane(mainPlane);
        smallPlanes.add(smallPlane);
    }


    private void addBuff() {
        long currentTimeMillis = System.currentTimeMillis();
        long l = currentTimeMillis - DataUtils.getBulletBuffsTime();
        if (l > DataUtils.getGoodsCd() * 1000){
            DataUtils.setBulletBuffsTime(currentTimeMillis);
            BulletBuff bulletBuff = bulletBuffs.get(0);
            if (!bulletBuff.isAlive()) {
                bulletBuff.setAlive(true);
            }
        }
    }


    // 背景移动的逻辑函数
    public void viewLogic() {
        if (bg_y > bg_y2) {
            bg_y += 10;
            bg_y2 = bg_y - background.getHeight();
        } else {
            bg_y2 += 10;
            bg_y = bg_y2 - background.getHeight();
        }
        if (bg_y >= background.getHeight()) {
            bg_y = bg_y2 - background.getHeight();
        } else if (bg_y2 >= background.getHeight()) {
            bg_y2 = bg_y - background.getHeight();
        }
        DataUtils.setBg_y(bg_y);
        DataUtils.setBg_y2(bg_y2);
    }
}